import Long from 'long';
export const isObject = obj => {
  if (obj == null) return false;
  return toString.call(obj) == '[object Object]';
};

export { default as cache } from './cache';

export const isFunction = obj => {
  return typeof obj === 'function';
};
export const isArray = obj => {
  return Array.isArray(obj);
};

export const isDate = function (val) {
  return val instanceof Date;
};

export const clearNull = data => {
  if (data == null) return data;
  for (const key in data) {
    if (data[key] === '' || data[key] === undefined) {
      delete data[key];
    }
  }
  return data;
};

export const isHttp = function (str) {
  return typeof str == 'string' && (str.startsWith('http://') || str.startsWith('https://'));
};

const Number = '0123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';

export const unShort = s => {
  let result = Long.fromNumber(0);
  if (typeof s === 'string' && s) {
    s = s.trim();
    let l = s.length;
    let m = Number.length;
    for (let x = 0; x < l; x++) {
      result = result.add(Number.indexOf(s[l - 1 - x]) * Math.pow(m, x));
    }
  }
  return result.toString();
};

export const appendQuery = function (url, params) {
  const query = parseQuery(params);
  if (!query) return url;
  if (url.indexOf('?') >= 0) {
    return url + '&' + query;
  }
  return url + '?' + query;
};

export const parseQuery = function (params) {
  var parts = [];
  if (!params) return '';
  clearNull(params);
  for (const key in params) {
    if (Object.hasOwnProperty.call(params, key)) {
      const val = params[key];
      if (val === null || typeof val === 'undefined') {
        continue;
      }
      if (Array.isArray(val)) {
        val.forEach((v, i) => {
          parts.push(`${key}[${i}]=${encodeURIComponent(v)}`);
        });
      } else if (isDate(val)) {
        parts.push(`${key}=${encodeURIComponent(val.format())}`);
      } else if (isObject(val)) {
        parts.push(`${key}=${encodeURIComponent(JSON.stringify(val))}`);
      } else {
        parts.push(`${key}=${encodeURIComponent(val)}`);
      }
    }
  }
  return parts.join('&');
};

export const parseParams = function (query) {
  let [path, args] = query.split('?');
  args = args || path;
  const params = {};
  args.split('&').forEach(arg => {
    var [key, value] = arg.split('=');
    params[key] = value || '';
  });
  return params;
};

export const extend = function () {
  var options,
    name,
    src,
    copy,
    copyIsArray,
    clone,
    target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false;
  if (typeof target === 'boolean') {
    deep = target;
    target = arguments[1] || {};
    i = 2;
  }
  if (typeof target !== 'object' && !isFunction(target)) {
    target = {};
  }
  if (length === i) {
    target = this;
    --i;
  }
  for (; i < length; i++) {
    if ((options = arguments[i]) != null) {
      for (name in options) {
        src = target[name];
        copy = options[name];
        if (target === copy) {
          continue;
        }
        if (deep && copy && (isObject(copy) || (copyIsArray = isArray(copy)))) {
          if (copyIsArray) {
            copyIsArray = false;
            clone = src && isArray(src) ? src : [];
          } else {
            clone = src && isObject(src) ? src : {};
          }
          target[name] = extend(deep, clone, copy);
        } else if (copy !== undefined) {
          target[name] = copy;
        }
      }
    }
  }
  return target;
};

export const trimStart = function (str, trimChar) {
  if (str.startsWith(trimChar)) {
    return trimStart(str.substr(trimChar.length), trimChar);
  }
  return str;
};

export const trimEnd = function (str, trimChar) {
  if (str.endsWith(trimChar)) {
    return trimEnd(str.substr(0, str.length - trimChar.length), trimChar);
  }
  return str;
};
